<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * this class user to generate voucher
 * 代金券的主要操作包括：
 * 1）系统管理员添加代金券类型，并指定金额，如10元，20元等
 * functions:
 * onShowVoucherTypeList（）
 * onShowAddVoucherType（）
 * onAddVoucherType（）
 * getVoucherType($typeData):这个函数用来通过ID，名字等来获取代金券类型
 * getCurrentVoucherType():这个函数用来获取当前的类型，一般来说，
 * 用这个函数可以避免总是传递类型参数，并且可以随时拿到当前的类型
 * addVoucherType($typeData):这个函数是真正添加类型的地方，数据库操作在这里完成
 * getVoucherTypeList($context):这个函数是获取类型列表的地方，一般来说，在这里完成数据操作
 * 2）系统管理员设置代金券的申请规则，比如，谁可以申请，是否需要批准，有效期等等
 * 申请规则实际上是一种权限设置，保存在permit表里面。对permit表的操作都通过BAPermitCooker来
 * 完成，涉及的操作包括：addPermit,getPermit, getPermitList,checkPermit，getCurrentPermit
 * UI操作函数包括：
 * onShowPermitList
 * onShowAddPermit
 * onAddPermit
 * 设置的权限包括：
 * 批准方式(permit)：直接批准，需要审批，生日代金券等
 * 申请人资格（role):可以申请代金券的资格
 * 申请截止时间(expireTime):申请截止时间 * 
 * 3）客户打开客户端页面的时候，将会显示代金券申请列表，代金券领取列表，以及客户拥有的代金券列表
 * 在客户的代金券主页，将会分别显示：
 * 客户代金券列表－客户拥有的代金券列表
 * 代金券领取列表－客户可以领取的代金券列表
 * 代金券申请列表－客户可以申请的代金券列表（需要批准）
 * 代金券领取列表：
 * 就是批准方式为直接批准的代金券类型，当客户满足申请人资格时候，就显示在客户的领取列表里面
 * 代金券申请列表：
 * 批准方式为需要审批的代金券类型，当客户满足申请人资格时候，显示在客户的申请列表里面
 * UI函数包括：
 * onShowUserVoucherHome:显示用户代金券首页
 * onShowUserVoucherList:用户的代金券列表
 * onShowUserAddableVoucherList:
 * onShowUserApprovableVoucherList:
 * getUserVoucherList
 * getUserAddableVoucherList
 * getUserApprovableVoucherList
 * 4）机构管理员端可以显示客户可用的代金券列表，并且可以使用代金券（用代金券支付账单）
 * 用户的代金券列表也可以显示在管理员页面，管理员通过输入手机号获取用户的代金券列表
 * 在管理员页面，管理员可以选择来支付（先实现直接支付的模式，以后实现需要批准的模式。是否需要
 * 批准，将由客户来决定，客户可以在用户列表里面设置是否需要批准）
 * 相关函数包括：
 * getUserVoucherList:和客户端的代金券列表一样，只是操作不同，管理员有“使用”的操作
 * 5）管理员使用代金券的时候，可以用两种方式，一种是直接使用，一种是需要客户同意，如果设置为需要客户同意
 * 就发送客户同意列表给客户，客户点击同意以后才可以使用
 * 管理员选择消费的代金券以后，如果需要客户同意，就点提交客户同意按钮，然后将产生一个使用的代金券列表，
 * 并发送给客户，客户点击同意按钮后，完成使用代金券操作（以后实现）
 * 函数包括：
 * onShowUserConsumingVoucherList
 * getUserConsumingVoucherList
 * onShowAddConsumingVoucher
 * onAddConsumingVoucher
 * 6）管理员使用了代金券以后，需要发送代金券消费列表给客户
 * 管理员使用了代金券以后，将会发送信息给客户，并且告知客户使用的代金券列表
 * 相关函数包括：
 * onShowUserConsumedVoucherList:一般只是包括某一次消费的代金券列表
 * getUserConsumedVoucherList
 * onShowAddConsumedVoucher
 * onAddConsumedVoucher
 * 7）客户随时可以查看代金券消费记录
 * 显示客户的代金券消费记录，客户和管理员都可以看，
 * 主要的函数包括：
 * onShowUserConsumedVoucherHistory
 * getUserConsumedVoucherHistory
 *
 * @author jianfeng
 */
class BAVoucherCooker extends BAEventCooker {

    const Voucher_Type_Normal = 'voucher_normal';
    const Voucher_Type_Birth = 'voucher_birth';
    const Permit_Allow_Add = 'allow_add_voucher';
    const Permit_Allow_Approve = 'allow_approve_voucher';
    const Voucher_Not_Used = 'not_used_voucher';
    const Voucher_Used = 'used_voucher';

    /**
     * 和voucherType有关的函数
     */
    public function onShowVoucherTypeList($control = NULL) {
        //$opName = Blyn::app()->getActiveOperation()->getName();
        if (!$control instanceof BUIControl) {
            $control = $this->updateControl;
        }

        $eventHome = $this->getCurrentEventHome();

        $control->addRenderView('showTypeList', 'voucherType_list_' . $eventHome, array('voucherTypeList' => $this->getVoucherTypeList('arrayList')));
    }

    public function onShowChooseVoucherType() {
        $this->updateControl->addRenderView('voucherType_add_choose');
    }

    public function onShowAddVoucherType($voucherTypeId = NULL) {

        $preVoucherType = NULL;

        $viewData = array();
        if ($voucherTypeId == NULL) {
            $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');
        }
        $viewData['voucherTypeId'] = $voucherTypeId;

        if ($voucherTypeId != NULL && $voucherTypeId > 0) {
            $voucherType = $this->getVoucherType($voucherTypeId);
            $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);
            $viewData['voucherType'] = $voucherType;
        }

        /**
         * 添加新类型的时候，需要先选择类型
         */
        if ($preVoucherType == NULL) {
            $preVoucherTypeMediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'choose_voucherType');
            if ($preVoucherTypeMediaList != NULL) {
                $preVoucherTypeMedia = $preVoucherTypeMediaList['preVoucherType'];
                $preVoucherType = $preVoucherTypeMedia->content;
            }
        }

        $viewData['preVoucherType'] = $preVoucherType;

        $viewData['viewData'] = $viewData;

        $this->updateControl->addRenderView('voucherType_add', 'voucherType_add', $viewData);
    }

    public function showAddVoucherTypeInfo($renderControl = NULL, $viewData = NULL) {

        if ($viewData == NULL)
            $viewData = array();

        $model = new BDynamicFormModel();
        $typeNameField = 'media_name_add_voucherType';
        $typeAliasField = 'media_alias_add_voucherType';
        $templateField = 'media_template_add_voucherType';
        $moneyField = 'media_money_add_voucherType';
        $validTimeUnitField = 'media_validTimeUnit_add_voucherType';
        $validTimeLengthField = 'media_validTimeLength_add_voucherType';

        $model->addField($typeNameField);
        $model->addField($typeAliasField);
        $model->addField($templateField);
        $model->addField($moneyField);
        $model->addField($validTimeUnitField);
        $model->addField($validTimeLengthField);

        //$type = $this->getCurrentVoucherType();
        $typeId = $this->activeLink->getLinkVariable('voucherTypeId');
        $type = NULL;
        if ($typeId != NULL) {
            $type = $this->getVoucherType($typeId);
        }

        if ($type == NULL) {
            if (isset($viewData['voucherType'])) {
                $type = $viewData['voucherType'];
            }
            if (isset($viewData['voucherTypeId'])) {
                $typeId = $viewData['voucherTypeId'];
                $type = $this->getVoucherType($typeId);
            }
        }

        if ($type != NULL) {

            $typeId = $type->getId();

            $typeAttributeTable = new BAAttributeSheet($type);

            $typeList = $typeAttributeTable->getList(array('itemData' => array('voucherTypeId' => $typeId)));

            //将已经存在的数据放进MODEL里面
            if ($typeList instanceof BTreeList) {
                if ($typeList->getItem('name') != NULL)
                    $model->$typeNameField = $typeList->getItem('name')->getValue();
                if ($typeList->getItem('alias') != NULL)
                    $model->$typeAliasField = $typeList->getItem('alias')->getValue();
                if ($typeList->getItem('template') != NULL)
                    $model->$templateField = $typeList->getItem('template')->getValue();
                if ($typeList->getItem('validTimeUnit') != NULL)
                    $model->$validTimeUnitField = $typeList->getItem('validTimeUnit')->getValue();
                if ($typeList->getItem('validTimeLength') != NULL)
                    $model->$validTimeLengthField = $typeList->getItem('validTimeLength')->getValue();
            }

            if ($typeList->getItem('money') != NULL) {
                $model->$moneyField = $typeList->getItem('money')->getValue();
            }
        }

        $viewData2 = array(
            'model' => $model,
            'typeNameField' => $typeNameField,
            'typeAliasField' => $typeAliasField,
            'templateField' => $templateField,
            'moneyField' => $moneyField,
            'validTimeUnitField' => $validTimeUnitField,
            'validTimeLengthField' => $validTimeLengthField,
        );
        $viewData+= $viewData2;

        if ($renderControl instanceof BUIControl) {
            $renderControl->addRenderView('addTypeInfo', 'voucherType_add_info', $viewData);
            $renderControl->render();
            return;
        }
        $this->updateControl->addRenderView('addVoucherTypeInfo', 'voucherType_add_info', $viewData);
    }

    /**
     * this function use to add voucher type.
     * usually each space can add several type of voucher
     * use this function to catch data from input and create voucher type
     */
    public function onAddVoucherType() {
        //$typeId = $this->activeLink->getLinkVariable('voucherTypeId');
        $preVoucherType = $this->activeLink->getLinkVariable('preVoucherType');
        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'add_voucherType');

        $itemData = array();
        foreach ($mediaList as $media) {
            $name = $media->name;
            $value = $media->content;
            if ($value != NULL || $value != '') {
                $itemData[$name] = $value;
            }
        }

        //adjust type name
        if (is_string($preVoucherType) && $preVoucherType != NULL) {
            $typeName = $itemData['name'];
            if (strpos($typeName, $preVoucherType) === FALSE) {
                $itemData['name'] = $preVoucherType . '.' . $itemData['name'];
            }
        }

        $type = $this->addVoucherType($itemData['name'], $itemData['alias'], $itemData);

        /**
          //add permit for type,以下添加默认的申请设置
          $permitData['voucherTypeId'] = $type->getId();
          //默认是机构客户都可以申请卡
          $permitData['roleId'] = BARoleCooker::getSpaceCustomerRole()->getId();
          //默认情况下，不需要审批，自动添加卡
          $permitData['permit'] = self::Permit_Allow_Add;

          $permitCooker = new BAPermitCooker();

          $this->addVoucherTypePermit($permitData, $type);
         * 
         */
        $this->onShowAddVoucherType($type->getId());
    }

    public function onDelVoucherType() {
        $typeId = $this->activeLink->getLinkVariable('voucherTypeId');
        if ($typeId != NULL) {
            //$itemData = array();
            //check if exist type
            //$itemData['voucherTypeId'] = $typeId;
            $typeTable = new BASpaceSheet('voucherType');
            $typeTable->deleteList($typeId);
        }
        $this->onShowVoucherTypeList();
    }

    public function addVoucherType($name, $alias = null, $data = NULL) {

        $voucherTypeRoot = $this->getVoucherTypeRoot();

        if ($alias == NULL) {
            $alias = $name;
        }
        $type = $voucherTypeRoot->addChild(array('name' => $name, 'value' => $alias));
        if ($type != NULL) {
            $itemData = array();
            //check if exist type
            $itemData['voucherTypeId'] = $type->getId();
            $typeAttributeTable = new BAAttributeSheet($type);
            $list = $typeAttributeTable->getList(array('itemData' => $itemData));

            if ($list == NULL) {
                $list = $typeAttributeTable->getNewList();
            }

            $itemData['name'] = $name;
            $itemData['alias'] = $alias;
            if (is_array($data)) {
                $itemData+=$data;
            }

            //check if data changed, if not, no need to save
            $list2 = $typeAttributeTable->getList(array('itemData' => $itemData));
            if ($list2 == NULL)
                $list->addItems($itemData);

            return $type;
        }
        return FALSE;
    }

    public static function getPreVoucherTypeList($data = NULL) {

        $typeList = array(self::Voucher_Type_Normal => '普通代金券');

        return $typeList;
    }

    public static function getPreVoucherTypeAlias($preVoucherType) {
        $typleList = self::getPreVoucherTypeList();
        if (isset($typleList[$preVoucherType])) {
            return $typleList[$preVoucherType];
        }
        return $preVoucherType;
    }

    protected function getVoucherTypeRoot() {
        $category = new BACategory();
        $categoryRoot = $category->getRootNode();
        $voucherTypeRoot = $categoryRoot->getChild('voucherType');
        if ($voucherTypeRoot == NULL) {
            $voucherTypeRoot = $categoryRoot->addChild('voucherType');
        }
        return $voucherTypeRoot;
    }

    /**
     * 
     * @param string formate, can be aliasList, nameList,objectList,arrayList
     * @param type $data
     * @return type
     */
    public function getVoucherTypeList($formate = 'aliasList', $preVoucherType = null, $data = NULL) {

        $parent = $this->getVoucherTypeRoot();

        if ($preVoucherType != NULL) {
            $parent = $parent->getChild($preVoucherType);
        }

        $children = $parent->getChildrenAsLeaf();

        if (strtolower($formate) == 'objectlist') {
            return $children;
        }

        $list = array();

        foreach ($children as $id => $type) {

            if (strtolower($formate) == 'arraylist') {
                $item = array();
                $item['id'] = $id;
                $item['name'] = $typeName = $type->getName();
                $item['alias'] = $type->getValue();

                $tNames = explode('_', $typeName);
                $appName = $tNames[0];
                $item['appName'] = $appName;
//                $item['permit'] = $this->getVoucherTypePermit($id);

                $list[$id] = $item;
            }
            if (strtolower($formate) == 'namelist') {
                $list[$id] = $type->getName();
            }
            if (strtolower($formate) == 'aliaslist') {
                $list[$id] = $type->getValue();
            }
        }

        return $list;
    }

    public function getVoucherType($nameOrId, $data = NULL) {

        if (is_numeric($nameOrId) && $nameOrId > 0) {
            return new BACategory($nameOrId);
        }

        if (is_string($nameOrId) && $nameOrId != NULL && $nameOrId != '') {
            $voucherTypeRoot = $this->getVoucherTypeRoot();
            $voucherType = $voucherTypeRoot->getChild($nameOrId);

            return $voucherType;
        }

        if ($nameOrId instanceof BACategory) {
            return $nameOrId;
        }

        return FALSE;
    }

    public function getVoucherTypeAlias($voucherType) {

        if ($voucherType instanceof BACategory) {
            return $voucherType->getValue();
        }
    }

    public function getVoucherTypeByVoucher($voucher) {

        $voucher = $this->getVoucher($voucher);

        if ($voucher != NULL) {
            $voucherTypeItem = $voucher->getItem('voucherTypeId');
            if ($voucherTypeItem != NULL) {
                $voucherTypeId = $voucherTypeItem->getValue();
                return $this->getVoucherType($voucherTypeId);
            }
        }
        return FALSE;
    }

    public function getVoucherTypeTemplateData($preVoucherType = NULL, $data = NULL) {
        return array();
    }

    public function getPreVoucherTypeFromVoucherType($voucherType) {
        $voucherType = $this->getVoucherType($voucherType);

        if ($voucherType instanceof BACategory) {
            $parent = $voucherType->getParent();
            if ($parent != NULL) {
                return $parent->getName();
            }
        }
        return FALSE;
    }

    public function getCurrentPreVoucherType($data = NULL) {

        $voucherType = $this->getCurrentVoucherType();
        if ($voucherType != NULL) {
            return $this->getPreVoucherTypeFromVoucherType($voucherType);
        }

        $preVoucherType = $this->activeLink->getLinkVariable('preVoucherType');

        if ($preVoucherType != NULL) {
//update value in context variable
            Blyn::app()->getUIManager()->getCurrentScreen()->addContextVariable('preVoucherType', $preVoucherType);
        } else {
            if ($preVoucherType == NULL) {
                //try to find from context variable
                $preVoucherType = Blyn::app()->getActiveOperation()->getContextVariable('preVoucherType');
            }
        }

        return $preVoucherType;
    }

    public function getCurrentVoucherType($data = NULL) {
        $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');
        if ($voucherTypeId == NULL)
            $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');

        if (is_numeric($voucherTypeId) && $voucherTypeId > 0) {
//update value in context variable
            Blyn::app()->getActiveOperation()->addContextVariable('voucherTypeId', $voucherTypeId);
        } else {
            if ($voucherTypeId == NULL) {
                //try to find from context variable
                $voucherTypeId = Blyn::app()->getActiveOperation()->getContextVariable('voucherTypeId');
            }
        }

        if (is_numeric($voucherTypeId) && $voucherTypeId > 0) {
            $voucherType = new BACategory($voucherTypeId);
            return $voucherType;
        }
        return FALSE;
    }

    public function getVoucherTypeAttribute($name, $type = NULL) {

        if ($type == NULL) {
            $voucherType = $this->getCurrentVoucherType();
        } else {
            $voucherType = $this->getVoucherType($type);
        }

        if ($voucherType != NULL) {
            $typeAttributeTable = new BAAttributeSheet($voucherType);
            $attrList = $typeAttributeTable->getList();
            if ($attrList != NULL) {
                $attrItem = $attrList->getItem($name);
                if ($attrItem != NULL) {
                    return $attrItem->getValue();
                }
            }
        }
        return FALSE;
    }

    /**
     * 和代金券相关的函数
     */
    /**
     * use to show voucher list, 
     */

    /**
     * 显示机构的代金券列表，可以设置条件获取各种列表
     * 这个函数通常由管理员操作来获取机构的卡列表
     */
    public function onShowVoucherList() {

        $voucherType = $this->getCurrentVoucherType();
        $voucherTypeId = $voucherType->getId();

        $voucherView = $this->getVoucherList(NULL, $voucherType);

        $opName = Blyn::app()->getActiveOperation()->getName();

        $this->updateControl->addRenderView('voucher_list', 'voucher_list_' . $opName, array(
            'voucherView' => $voucherView,
            'voucherType' => $voucherType,
            'voucherTypeId' => $voucherTypeId));
    }

    /**
     * 添加代金券在以下几种情况下实现：
     * 1）用户领取代金券的时候，一般来说，领取的时候调用addVoucher来完成添加卡的操作
     * 2）申请代金券批准的时候，申请批准的时候，也将调用addVoucher来完成添加卡的操作
     * 3）管理人员添加卡的操作，只要管理员添加卡的时候需要调用这个函数来完成添加卡的操作
     */
    public function onShowAddVoucher() {

        $this->updateControl->addRenderView('voucher_add');
    }

    public function onShowAddVoucherInfo() {

        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'user_info');
        $userInfo = array();
        foreach ($mediaList as $media) {
            $userInfo[$media->name] = $media->content;
        }

        $userCooker = new BAUserCooker();
        $oUserInfo = $userCooker->getUserInfo($userInfo);
        /*
         * 在manager里面增加代金券，代金券类型由admin增加
         * 下面代码处理manager
         */
        $voucherId = $this->activeLink->getLinkVariable('voucherId');
        $voucherTable = new BASpaceSheet('voucher');

        $model = new BDynamicFormModel();
        $fixedVoucherIdField = 'media_fixedVoucherId_add_voucher';
        $mobileField = 'media_mobile_user_info';
        $genderField = 'media_gender_user_info';
        $surNameField = 'media_surName_user_info';
        $familyNameField = 'media_familyName_user_info';
        $birthField = 'media_birthField_user_info';
        $expireTimeField = 'media_expireTime_add_voucher';
        $descriptionField = 'media_description_add_voucher';

        $model->addField($fixedVoucherIdField);
        $model->addField($mobileField);
        $model->addField($genderField);
        $model->addField($familyNameField);
        $model->addField($surNameField);
        $model->addField($birthField);
        $model->addField($expireTimeField);
        $model->addField($descriptionField);

        //populate user info
        if ($oUserInfo->getItem('mobile') != NULL)
            $model->$mobileField = $oUserInfo->getItem('mobile')->getValue();
        if ($oUserInfo->getItem('gender') != NULL)
            $model->$genderField = $oUserInfo->getItem('gender')->getValue();
        if ($oUserInfo->getItem('familyName') != NULL)
            $model->$familyNameField = $oUserInfo->getItem('familyName')->getValue();
        if ($oUserInfo->getItem('surName') != NULL)
            $model->$surNameField = $oUserInfo->getItem('surName')->getValue();
        if ($oUserInfo->getItem('$oUserInfo') != NULL)
            $model->$surNameField = $oUserInfo->getItem('surName')->getValue();
        if ($oUserInfo->getItem('birthField') != NULL)
            $model->$birthField = $oUserInfo->getItem('birthField')->getValue();

        if ($voucherId != NULL && $voucherId > 0) {

            $voucher = $voucherTable->getListById($voucherId);

            //将已经存在的活动数据放进MODEL里面
            if ($voucher->getItem('fixedVoucherId') != NULL)
                $model->$fixedVoucherIdField = $voucher->getItem('fixedVoucherId')->getValue();
            if ($voucher->getItem('expireTime') != NULL)
                $model->$expireTimeField = $voucher->getItem('expireTime')->getValue();
            if ($voucher->getItem('description') != NULL)
                $model->$descriptionField = $voucher->getItem('description')->getValue();
        }else { //add a temporary voucher by userid_spaceid
            $voucher = $voucherTable->getTempList();
        }

        $this->updateControl->addRenderView('voucherAdd', 'voucher_add', array(
            'model' => $model,
            'fixedVoucherIdField' => $fixedVoucherIdField,
            'genderField' => $genderField,
            'surNameField' => $surNameField,
            'familyNameField' => $familyNameField,
            'mobileField' => $mobileField,
            'birthField' => $birthField,
            'expireTimeField' => $expireTimeField,
            'descriptionField' => $descriptionField,
            'voucher' => $voucher,
            'voucherId' => $voucherId));
    }

    public function onShowVoucher() {

        $voucher = $this->getCurrentVoucher();
        $userCooker = new BAUserCooker();
        $permitCooker = new BAPermitCooker();
        $voucherInfo = array();

        if ($voucher != NULL) {
            $voucherType = $this->getVoucherTypeByVoucher($voucher);
            $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);
            $userInfoId = $voucher->getItem('userInfoId')->getValue();
            $permitId = $voucher->getItem('permitId')->getValue();
            $oUserInfo = $userCooker->getUserInfo($userInfoId);
            $permit = $permitCooker->getPermit($permitId);

            if ($oUserInfo != NULL) {
                $userData = $oUserInfo->getItemsInArray();
                $voucherInfo+=$userData;
            }

            if ($permit != NULL) {
                $permitData = $permit->getItemsInArray();
                $voucherInfo+=$permitData;
            }
            $voucherInfo['preVoucherType'] = $preVoucherType;
            $voucherInfo['voucherTypeAlias'] = $voucherType->getValue();
        }

        $this->updateControl->addRenderView('showVoucher', 'voucher_display', array('voucherInfo' => $voucherInfo));
    }

    public function onAddVoucher() {

        $userMediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'user_info');

        //add user data into user table
        if ($userMediaList != NULL) {
            $userCooker = new BAUserCooker();
            $userData = array();
            foreach ($userMediaList as $media) {
                $userData[$media->name] = $media->content;
            }
            //用户数据通过link传递过来
            if (!isset($userData['userId']) && $this->activeLink->getLinkVariable('userId') != NULL) {
                $userData['userId'] = $this->activeLink->getLinkVariable('userId');
            }
            if (!isset($userData['mobile']) && $this->activeLink->getLinkVariable('mobile') != NULL) {
                $userData['mobile'] = $this->activeLink->getLinkVariable('mobile');
            }
            if (!isset($userData['email']) && $this->activeLink->getLinkVariable('email') != NULL) {
                $userData['email'] = $this->activeLink->getLinkVariable('email');
            }
            $oUserInfo = $userCooker->addUserInfo($userData);
        }

        $mvoucherId = $this->activeLink->getLinkVariable('voucherId');

        $voucherTable = new BASpaceSheet('voucher', $this->getCurrentVoucherType());

        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'add_voucher');

        $itemData = array();
        if (isset($oUserInfo) && $oUserInfo != NULL) {
            $itemData['userInfoId'] = $oUserInfo->getId();
        }

        foreach ($mediaList as $media) {
            $name = $media->name;
            $value = $media->content;
            $itemData[$name] = $value;
        }

        $voucher = $this->addVoucher(NULL, $mvoucherId, $itemData);

        $this->onShowVoucherList();
    }

    public function onDelVoucher() {
        $voucherId = $this->activeLink->getLinkVariable('voucherId');
        if ($voucherId != NULL) {
            $voucherTable = new BASpaceSheet('voucher', $this->getCurrentVoucherType());
            $voucherTable->deleteList($voucherId);
        }
        $this->onShowVoucherList();
    }

    /**
     * this function use to display member voucher for member
     */
    /*
      public function onShowVoucher() {
      $voucherId = $this->activeLink->getLinkVariable('voucherId');
      $this->updateControl->addRenderView('displayVoucher', 'voucherDisplay', array('voucherId' => $voucherId));
      }
     * 
     */

    public function addVoucher($voucherType = NULL, $itemData = NULL, $voucherId = NULL) {

        $voucher = NULL;

        if ($voucherType == NULL) {
            $voucherType = $this->getCurrentVoucherType();
        } else {
            $voucherType = $this->getVoucherType($voucherType);
        }

        if ($itemData == NULL) {
            $itemData = array();
        }

        if ($voucherType != NULL) {

            $itemData['voucherTypeId'] = $voucherType->getId();

            $voucherId = NULL;
            $voucherTable = new BASpaceSheet('voucher', $voucherType);
            if (is_numeric($voucherId) && $voucherId > 0) {
                $voucher = $voucherTable->getListById($voucherId);
                if ($voucher->getName() != 'list' . $voucher->getId()) {
                    $voucher->name = 'list' . $voucher->getId();
                    $voucher->setOwner($this->getCurrentVoucherType());
                    $voucher->save();
                }
            }

            if (isset($itemData['voucherId'])) {
                $voucherId = $itemData['voucherId'];
                $voucher = $voucherTable->getList(array('itemData' => array('voucherId' => $itemData['voucherId'])));
            } else {
                $voucher = $voucherTable->getList(array('itemData' => $itemData));
            }

            if ($voucher == NULL) {
                $voucher = $voucherTable->getNewList();
            }

            if (!isset($itemData['voucherId'])) {
                $itemData['voucherId'] = 'voucher' . $voucher->getId();
            }

            $itemData['status'] = self::Voucher_Not_Used;

            if ($voucher instanceof BTreeList) {
                $itemData['addTime'] = time();
                $voucher->addItems($itemData);
            }
        }

        return $voucher;
    }

    /**
     * 机构管理员用这个function来获取卡列表，并进行管理
     * 用户不用这个函数获取列表，用户用getUserVoucherList来获取用户的卡列表
     * @param type $voucherType
     * @param type $operation
     * @param type $data
     * @return type
     */
    public function getVoucherList($itemData = NULL, $voucherType = null, $format = 'aliasList', $operation = NULL, $data = NULL) {

        if ($voucherType == NULL) {
            $voucherType = $this->getCurrentVoucherType();
        }

        if ($operation == NULL) {
            $operation = Blyn::app()->getActiveOperation();
        }

        $voucherTable = new BASpaceSheet('voucher', $voucherType);
        $voucherView = $voucherTable->getView(array('itemData' => $itemData));

        return $voucherView;
    }

    public function getVoucher($itemData = NULL, $voucherType = NULL) {

        $voucherTable = new BASpaceSheet('voucher');

        if (is_numeric($itemData) && $itemData > 0) {
            return $voucherTable->getListById($itemData);
        }

        if ($itemData instanceof BTreeList) {
            return $itemData;
        }

        if (is_array($itemData)) {
            $voucherType = $this->getVoucherType($voucherType);
            $voucherTable = new BASpaceSheet('voucher', $voucherType);
            return $voucherTable->getList(array('itemData' => $itemData));
        }

        return FALSE;
    }

    public function getExpireTime($voucher = NULL) {

        if ($voucher == NULL) {
            $voucher = $this->getCurrentVoucher();
        } else {
            $voucher = $this->getVoucher($voucher);
        }

        if ($voucher instanceof BTreeList) {

            $voucherAddTime = $voucher->getItem('addTime')->getValue();

            $voucherType = $this->getVoucherTypeByVoucher($voucher);
            if ($voucherType != NULL) {
                $timeUnit = $this->getVoucherTypeAttribute('validTimeUnit', $voucherType);
                $timeLength = $this->getVoucherTypeAttribute('validTimeLength', $voucherType);
            }

            if ($timeLength != NULL && $timeUnit != NULL) {
                if ($timeLength > 1) {
                    $timeUnit .= 's';
                }
            }

            return strtotime('+ ' . $timeLength . ' ' . $timeUnit, $voucherAddTime);
        }
    }

    /**
     * ********************
     * 和用户卡相关的函数
     * ********************
     */

    /**
     * 显示可以用户的代金券领取列表和用户可以申请的卡的列表,将领取表和申请表都放在这里
     */
    public function onShowUserVoucherApplyList($voucherTypeId = NULL, $preVoucherType = NULL) {

        //$voucherType = $this->getCurrentVoucherType();
        //$preVoucherType = $this->getCurrentPreVoucherType();
        if ($voucherTypeId == NULL)
            $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');
        if ($preVoucherType == NULL)
            $preVoucherType = $this->activeLink->getLinkVariable('preVoucherType');

        $applyList = $this->getUserVoucherApplyList($voucherTypeId, $preVoucherType);
        $this->updateControl->addRenderView('userVoucherApplyList', 'voucher_apply_list', array(
            'applyView' => $applyList
        ));
    }

    public function onShowUserAddVoucher() {

        $userCooker = new BAUserCooker();
        $userInfo = $userCooker->getUserInfo();

        if ($userInfo == NULL) {//means user not register so far
            $this->updateControl->addRenderView('voucher_apply_list_header');
            $userInfoControl = new BUIThemedControl('addUserInfo');
            $this->updateControl->addChildControl($userInfoControl);
            $userCooker->showAddUserInfo($userInfoControl);
        } else {//if user register user info already
            $voucherType = $this->getCurrentVoucherType();
            $permitId = $this->activeLink->getLinkVariable('permitId');
            $permitCooker = new BAPermitCooker();
            $permit = $permitCooker->getPermit($permitId, 'object');
            $itemData = array();
            if ($permit != NULL) {
                $itemData['permitId'] = $permit->getId();
            }
            if ($userInfo != NULL) {
                $itemData['userInfoId'] = $userInfo->getId();
            }
            //$userInfoData = $userCooker->getUserInfo(NULL, 'array');
            //$itemData = $userInfoData;
            $this->addVoucher($voucherType, $itemData);
            $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);

            //$this->activeLink->addLinkVariable('voucherTypeId', NULL);
            $this->onShowUserVoucherApplyList('ALL');
        }
    }

    public function onShowUserApplyVoucher() {
        
    }

    public function onShowUserVoucherList() {

        //$voucherType = $this->getCurrentVoucherType();

        $voucherList = $this->getUserVoucherList();
        $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');
        $preVoucherType = $this->activeLink->getLinkVariable('preVoucherType');
        $applyList = $this->getUserVoucherApplyList($voucherTypeId, $preVoucherType);
        $applyListCount = count($applyList); //获得可领取会员卡的个数
        $this->updateControl->addRenderView('userVoucherList', 'voucher_list_member', array(
            'voucherView' => $voucherList
        ));
    }

    public function onShowUserVoucherListInMobile() {

        //$voucherType = $this->getCurrentVoucherType();

        $voucherList = $this->getUserVoucherList();
        $voucherTypeId = $this->activeLink->getLinkVariable('voucherTypeId');
        $preVoucherType = $this->activeLink->getLinkVariable('preVoucherType');
        $applyList = $this->getUserVoucherApplyList($voucherTypeId, $preVoucherType);
        $applyCount = count($applyList); //获得可领取会员卡的个数
        $this->updateControl->addRenderView('userVoucherList', 'voucher_list_member', array(
            'voucherView' => $voucherList,
            'applyCount' => $applyCount
        ));
    }

    public function onShowSpaceVoucherList() {
        //$voucherType = $this->getCurrentVoucherType();

        $voucherList = $this->getSpaceVoucherList();

        $this->updateControl->addRenderView('userVoucherList', 'voucher_list_manager', array(
            'voucherView' => $voucherList
        ));
    }

    public function onShowUserVoucherHome() {
        $this->updateControl->addRenderView('voucher_member_home');
    }

    /**
     * 在卡的可申请列表里面，用户点领取，将执行这个操作
     */
    public function onUserAddVoucher() {

        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'apply_voucher');

        $itemData = array();
        foreach ($mediaList as $media) {
            $itemData[$media->name] = $media->content;
        }

        if (isset($itemData['voucherTypeId'])) {
            $voucherTypeId = $itemData['voucherTypeId'];

            $voucherType = $this->getVoucherType($voucherTypeId);
            $memberPointCooker = new BAMemberPointCooker();

            //if it is 20元消费券,抵扣200积分并自动处理
            if (strpos($voucherType->getFullName(), 'payVoucher.yuan20')) {
                if ($memberPointCooker->deductMemberPoint($voucherType, 200) === TRUE) {
                    $voucher = $this->addVoucher($voucherType);
                    $this->updateControl->addRenderView('applyVoucher', 'voucher_list', array(
                        'voucherType' => $voucherType,
                        'voucher' => $voucher
                    ));
                }
            } else {//by default, send request for approvement
                $messageTable = new BAMessageSheet('applyVoucher');
                $itemData = array();
                $itemData['send_userId'] = Blyn::app()->getCurrentUser()->getId();
                $itemData['voucherTypeId'] = $voucherType->getId();

                $list = $messageTable->getList(array('itemData' => $itemData));

                //if exist, return status
                if ($list instanceof BTreeList) {
                    $status = $list->getItem('status')->getValue();
                    $this->updateControl->addRenderView('applyVoucherStatus', 'voucher_apply_status', array(
                        'status' => $status
                    ));
                } else {//if not exist, create a new message
                    $itemData['applyTime'] = time();
                    $itemData['send_userName'] = Blyn::app()->getCurrentUser()->getName();
                    $itemData['voucherTypeFullName'] = $voucherType->getFullName();
                    $itemData['voucherTypeAlias'] = $voucherType->getValue();
                    $itemData['status'] = 'pending';
                    $list = $messageTable->addList($itemData);
                    $this->updateControl->addRenderView('showApplyVoucherRequest', 'showApplyVoucherRequest', array(
                        'request' => $list
                    ));
                }
            }
        }

        $this->updateControl->addRenderView('applyVoucher_fail');
    }

    /**
     * 在可申请列表里面的申请卡的操作
     */
    public function onUserApplyVoucher() {
        
    }

    /**
     * 这个函数用来获取各种可申请的代金券列表
     * @param type $voucherType
     * @param type $status
     * @param type $data
     */
    public function getUserVoucherApplyList($voucherType = NULL, $preVoucherType = NULL, $permitInfo = NULL, $voucherInfo = NULL) {

        //用CACHE来提高性能，第一次会慢些，以后就会从CACHE里面拿，会变快，如果修改了PERMIT，那么，会更新CACHE
        $oldApplyList = Blyn::app()->getCurrentUser()->getCache('voucherApplyList');
        $applyList = NULL;

        $voucherTypeList = array();
        if ($voucherType != NULL && $this->getVoucherType($voucherType) != NULL) {
            $voucherType = $this->getVoucherType($voucherType);
            $voucherTypeList[$voucherType->getId()] = $voucherType;
        } else {
            $voucherTypeList = $this->getVoucherTypeList('objectList', $preVoucherType);
        }

        $permitCooker = new BCafePermitCooker();
        $userCooker = new BAUserCooker();
        $oUserInfo = $userCooker->getUserInfo();

        //用户没有注册，则不能申请
        if ($oUserInfo == NULL) {
            return FALSE;
        }

        //找出所有的可以申请设置
        foreach ($voucherTypeList as $vId => $voucherType) {
            //可以领取的代金券
            $permitList = $permitCooker->getPermitList(array(
                'permit' => self::Permit_Allow_Add,
                'voucherTypeId' => $vId));
            foreach ($permitList as $id => $permit) {
                $itemData = array();
                $itemData['permitId'] = $id;
                if ($oUserInfo != NULL)
                    $itemData['userInfoId'] = $oUserInfo->getId();

                $voucher = $this->getVoucher($itemData, $voucherType);
                if ($voucher == NULL) {//说明用户还没有领取或者没有加入申请列表
                    //如果已经保存过，从保存的数据中取出来
                    if (isset($oldApplyList[$id])) {
                        $oldChangeTime = $oldApplyList[$id];
                        $permitChangeTimeItem = $permit->getItem('lastChangeTime');
                        if ($permitChangeTimeItem) {//判断是否修改过
                            $permitChangeTime = $permitChangeTimeItem->getValue();
                            if ($permitChangeTime > $oldChangeTime) {
                                $isPermitChanged = TRUE;
                            }
                        }
                        $permitExpireTimeItem = $permit->getItem('expireTime');
                        $isPermitExpired = FALSE;
                        if ($permitExpireTimeItem) {
                            $expireTime = $permitExpireTimeItem->getValue();
                            if ($expireTime < time()) {
                                //如果已经过期，将不再放进新的申请列表里面
                                $isPermitExpired = TRUE;
                            }
                        }

                        //对生日代金券来说，超过领取期限（一般15天，在判断是否有效函数里面设置），就会过期
                        $permit = $permitCooker->getPermit($id);
                        if ($permitCooker->isMemberOfPermitType($permit, BAPermitCooker::PermitType_birthPermit)) {
                            $isPermitExpired = !$permitCooker->isBirthPermitValid($permit);
                        }

                        //对回访激励代金券来说，超过领取期限（一般15天），就会过期
                        if ($permitCooker->isMemberOfPermitType($permit, BCafePermitCooker::PermitType_PermitByBillTimeInterval)) {
                            $isPermitExpired = $permitCooker->isBillTimeIntervalPermitExpired($permit);
                        }

                        if (!isset($isPermitChanged) || $isPermitChanged == NULL) {
                            if (!$isPermitExpired) {
                                $applyList[$id] = $oldApplyList[$id];
                            }
                        }
                        continue;
                    }

                    //如果没有从旧的列表里面找到申请号，判断PERMIT是否是用户的可以添加的代金券，是就加入可加入列表里面
                    $result = $permitCooker->checkUserPermit($permit);
                    if ($result) {
                        if ($permit->getItem('lastChangeTime'))
                            $applyList[$id] = $permit->getItem('lastChangeTime')->getValue();
                        else {
                            $applyList[$id] = $permit;
                        }
                    }
                    /*
                      $permitData = array();

                      //$permitData['permit'] = $permit;
                      if ($preVoucherType != NULL)
                      $permitData['preVoucherType'] = $preVoucherType;
                      if ($voucherType != NULL) {
                      $voucherType = $this->getVoucherType($voucherType);
                      $permitData['voucherTypeId'] = $voucherType->getId();
                      $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);
                      $permitData['preVoucherType'] = $preVoucherType;
                      }
                      if (is_array($permitInfo) && $permitInfo != NULL)
                      $permitData+=$permitInfo;
                      //找出用户允许申请或者领取的申请项
                      $permitList = $permitCooker->getUserPermitList($permitData);
                     * 
                     */

                    //检查每个许可是否被用户使用过，如果没使用过，就加入申请列表
                    /*
                      foreach ($permitList as $id => $permit) {
                      //                        if ($oUserInfo != NULL) {
                      //                            $typeId = $permit->getItem('voucherTypeId')->getValue();
                      //                            $type = $this->getVoucherType($typeId);
                      //                            $voucherData = array();
                      //                            $voucherData['userInfoId'] = $oUserInfo->getId();
                      //                            $voucherData['permitId'] = $id;
                      //                            if ($permit->getItem('lastChangeTime'))
                      //                                $applyList[$id] = $permit->getItem('lastChangeTime')->getValue();
                      //                            else {
                      //                                $applyList[$id] = $permit;
                      //                            }
                      //                        } else {//如果还没有用户数据，就直接加入申请列表
                      if ($permit->getItem('lastChangeTime'))
                      $applyList[$id] = $permit->getItem('lastChangeTime')->getValue();
                      else {
                      $applyList[$id] = $permit;
                      }
                      //}
                      } */
                }
            }
        }

        /*
          foreach ($voucherTypeList as $id => $voucherType) {

          //先获取领取许可表
          $permitData = array();

          //$permitData['permit'] = $permit;
          if ($preVoucherType != NULL)
          $permitData['preVoucherType'] = $preVoucherType;
          if ($voucherType != NULL) {
          $voucherType = $this->getVoucherType($voucherType);
          $permitData['voucherTypeId'] = $voucherType->getId();
          $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);
          $permitData['preVoucherType'] = $preVoucherType;
          }
          if (is_array($permitInfo) && $permitInfo != NULL)
          $permitData+=$permitInfo;
          $permitList = $permitCooker->getUserPermitList($permitData);

          //检查每个许可是否被用户使用过，如果没使用过，就加入申请列表
          foreach ($permitList as $id => $permit) {
          if ($oUserInfo != NULL) {
          //如果已经有用户信息，检查用户是否有卡
          //如果在这个PERMIT下面还没有卡，
          //就加入申请列表
          $typeId = $permit->getItem('voucherTypeId')->getValue();
          $type = $this->getVoucherType($typeId);
          $voucherData = array();
          $voucherData['userInfoId'] = $oUserInfo->getId();
          $voucherData['permitId'] = $id;
          if (is_array($voucherInfo) && $voucherInfo != NULL)
          $voucherData+=$voucherInfo;
          $voucher = $this->getUserVoucher($type, $voucherData);
          if ($voucher == NULL) {
          $applyList[$id] = $permit;
          }
          } else {//如果还没有用户数据，就直接加入申请列表
          $applyList[$id] = $permit;
          }
          }
          }
         * 
         */
        if ($applyList != NULL)
            Blyn::app()->getCurrentUser()->setCache('voucherApplyList', $applyList);
        return $applyList;
    }

    /**
     * 用于获取用户的各种卡列表，包括正在申请的，已经申请的等等
     * @param type $voucherType
     * @param type $status
     * @param type $data
     */
    public function getUserVoucherList($format = NULL, $userData = NULL, $itemContext = NULL, $voucherType = NULL, $preVoucherType = NULL) {
        $voucherList = array();

        $userCooker = new BAUserCooker();
        if ($userData == NULL) {
            $oUserInfo = $userCooker->getUserInfo();
        } else {
            $oUserInfo = $userCooker->getUserInfo($userData);
        }

        if (!is_array($itemContext)) {
            $itemContext = array();
            $itemContext['status'] = self::Voucher_Not_Used;
        }

        if ($oUserInfo != NULL) {
            $itemContext['userInfoId'] = $oUserInfo->getId();

            if ($voucherType != NULL) {
                $itemContext['voucherTypeId'] = $voucherType->getId();
                $voucherTable = new BASpaceSheet('voucher', $voucherType);
            } else {
                $voucherTable = new BASpaceSheet('voucher', BTreeTable::All_Owner);
                if ($preVoucherType != NULL) {
                    $itemContext['perVoucherType'] = $preVoucherType;
                }
            }

            $voucherList = $voucherTable->getView(array('itemData' => $itemContext));
        }
        if ($format == 'aliasList') {
            $aliasList = array();
            foreach ($voucherList as $id => $voucher) {
                $voucherType = $this->getVoucherTypeByVoucher($voucher);
                $typeAlias = $this->getVoucherTypeAlias($voucherType);
                $aliasList[$id] = $typeAlias;
            }
            return $aliasList;
        }
        return $voucherList;
    }

    public function getSpaceVoucherList($format = NULL, $itemContext = NULL, $voucherType = NULL, $preVoucherType = NULL) {
        $voucherList = array();

        if (!is_array($itemContext)) {
            $itemContext = array();
        }

        //$itemContext['status'] = self::Voucher_Not_Used;

        $voucherTable = new BASpaceSheet('voucher', BTreeTable::All_Owner);

        if ($voucherType == NULL) {
            $voucherType = $this->getCurrentVoucherType();
        } else {
            $voucherType = $this->getVoucherType($voucherType);
        }

        if ($voucherType instanceof BACategory) {
            $itemContext['voucherTypeId'] = $voucherType->getId();
        }

        $voucherList = $voucherTable->getView(array('itemData' => $itemContext));

        if ($format == 'aliasList') {
            $aliasList = array();
            foreach ($voucherList as $id => $voucher) {
                $voucherType = $this->getVoucherTypeByVoucher($voucher);
                $typeAlias = $this->getVoucherTypeAlias($voucherType);
                $aliasList[$id] = $typeAlias;
            }
            return $aliasList;
        }
        return $voucherList;
    }

    /**
     * this function use to authenticate user mobile and to save user openid     
     */
    public function onAuthUser() {
        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'user_Info');
        $user = Blyn::app()->getCurrentUser();
        foreach ($mediaList as $key => $media) {
            $user->addAttribute('userInfo.' . $key, $media->content);
        }
        $this->updateControl->addRenderView('displayVoucher', 'voucher_display');
    }

    /**
     * this function will show apply page for applying memberPoint voucher 
     * @param type $data
     */
    /*
      public function onShowApplyMemberPointVoucher($data = NULL) {
      $voucher = $this->getCurrentVoucher();
      $this->updateControl->addRenderView('showApplyMemberPointVoucher', 'voucher_apply_memberPointVoucher', array(
      'memberPointVoucher' => $voucher
      ));
      }

      public function onShowUserVoucherApplyList() {
      $user = Blyn::app()->getCurrentUser();
      $mobileAttr = $user->getAttribute('userInfo.mobile');
      if ($mobileAttr == NULL || $mobileAttr->getValue() == NULL) {//ask user input mobile
      $this->updateControl->addRenderView('request_user_mobile');
      return;
      }

      $applyList = $this->getUserVoucherApplyList();
      $this->updateControl->addRenderView('userVoucherApplyList', 'user_voucher_apply_list', array(
      'applyList' => $applyList
      ));
      }

      public function onShowUserVoucherList() {
      $user = Blyn::app()->getCurrentUser();
      $mobileAttr = $user->getAttribute('userInfo.mobile');
      if ($mobileAttr != NULL) {
      $mobile = $mobileAttr->getValue();
      $userInfo = array();
      $userInfo['mobile'] = $mobile;
      $voucherList = $this->getUserVoucherList(self::VoucherType_Voucher_Voucher, $userInfo);
      if ($voucherList == NULL) {
      $voucherList = array();
      }
      $this->updateControl->addRenderView('userVoucherList', 'user_voucher_list', array(
      'voucherList' => $voucherList
      ));
      return;
      }

      //if not provide mobile, go to apply memberPoint voucher page
      $this->onShowUserVoucherApplyList();
      }
     * 
     */

    /**
     * some times, member should apply for voucher, this function
     * will use to handle apply action
     * result of this function should be :
     * 1)directly approve apply
     * 2)send request for processing
     */

    /**
     * this function use to handle request
     * usually should get request type from input
     * the can corresponding function to do some action
     */
    public function onProcessRequest() {
        
    }

    public function onShowRequestList() {
        
    }

    /**
     * some action will send request, then use this function to send request
     * @param type $requestType
     * @param type $message
     * @param type $data
     */
    public function sendRequest($requestType, $message, $data = NULL) {
        
    }

    /**
     * this funtion maybe called onApplyVoucher, also maybe called when processing 
     * apply request
     */
    public function approveApplyVoucher() {
        
    }

    /*
      public function applyVoucher($voucherType = null, $voucherInfo = NULL, $userInfo = NULL) {

      if (!is_array($userInfo)) {
      $userInfo = array();
      $userInfo['userId'] = Blyn::app()->getCurrentUser()->getId();
      }

      return $this->processApplyVoucher($voucherType, $voucherInfo, $userInfo);
      }
     * 
     */

    /**
     * 
     * @param type $voucherType
     * @param type $voucherInfo
     * @return type
     */
    protected function processApplyVoucher($voucherType, $voucherInfo, $userInfo = NULL) {

        $voucherType = $this->getVoucherType($voucherType);

        //for voucher
        if (strpos($voucherType->getFullName(), self::VoucherType_Voucher_Voucher)) {
            $permit = $this->checkApplyVoucherPermit($voucherType, $voucherInfo);
            //auto create voucher
            if ($this->checkApplyVoucherPermit(self::Permit_Allow_Add, $voucherType, $userInfo)) {
                $voucher = $this->addVoucher($voucherType, $voucherInfo);
                return array('action' => 'createVoucher', 'status' => 'completed', 'voucher' => $voucher);
            }
            //send approvable message
            if ($this->checkApplyVoucherPermit(self::Permit_Allow_Approve, $voucherType, $userInfo)) {
                $messageTable = new BAMessageSheet('applyVoucherMessage');
                $message = array();
                $message['applicantId'] = Blyn::app()->getCurrentUser()->getId();
                $message['time'] = time();
                $message['voucherTypeId'] = $voucherType->getId();
                $message+=$voucherInfo;
                if (is_array($userInfo))
                    $message+=$userInfo;
                $oMessage = $messageTable->addList($message);
                return array('action' => 'sendApproveRequest', 'status' => 'completed', 'message' => $oMessage);
            }
        }

        //process for memberPoint voucher
        if (strpos($voucherType->getFullName(), self::VoucherType_MemberPoint_Voucher)) {
            //auto create memberPoint account and voucher if allow add voucher
            if ($this->checkApplyVoucherPermit(self::Permit_Allow_Add, $voucherType, $userInfo)) {
                $memberPointCooker = new BAMemberPointCooker();
                //get memberPoint Type
                $memberPointType = $voucherType->getItem('memberPointType')->getValue();
                $memberPointType = $memberPointCooker->getMemberPointType($memberPointType);

                //get memberPointAccount
                $account = $memberPointCooker->getMemberPointAccount($userInfo, $memberPointType);

                if ($account == NULL) {//create it if account not exist
                    $account = $memberPointCooker->addMemberPointAccount($memberPointType, $userInfo);
                }

                if ($account != NULL) {
                    $voucherInfo['memberPointAccountId'] = $account->getId();
                }

                $voucher = $this->addVoucher($voucherType, $voucherInfo);
                return array('action' => 'createVoucher', 'status' => 'completed', 'voucher' => $voucher);
            }
            //send approvable message
            if ($this->checkApplyVoucherPermit(self::Permit_Allow_Approve, $voucherType, $userInfo)) {
                $messageTable = new BAMessageSheet('applyVoucherMessage');
                $message = array();
                $message['applicantId'] = Blyn::app()->getCurrentUser()->getId();
                $message['time'] = time();
                $message['voucherTypeId'] = $voucherType->getId();
                $message+=$voucherInfo;
                if (is_array($userInfo))
                    $message+=$userInfo;
                $oMessage = $messageTable->addList($message);
                return array('action' => 'sendApproveRequest', 'status' => 'completed', 'message' => $oMessage);
            }
        }

        return FALSE;
    }

    protected function checkApplyVoucherPermit($permit, $voucherType, $userInfo = NULL) {
        $permitCooker = new BAPermitCooker();
        $voucherType = $this->getVoucherType($voucherType);

        $permitData = array();
        $permitData['voucherTypeId'] = $voucherType->getId();
        $permitData['permit'] = $permit;

        $userCooker = new BAUserCooker();
        $user = $userCooker->getUserByInfo($userInfo);
        if ($user instanceof BUser) {
            $roles = BRole::findUserRoles($user, NULL, TRUE);
            $roleIdList = array();
            foreach ($roles as $id => $role) {
                $roleIdList[$id] = $id;
            }
            $permitData['roleId'] = $roleIdList;
        }

        return $permitCooker->checkPermit($permitData);
    }

    public function getCurrentVoucher($data = NULL) {
        $voucherId = $this->activeLink->getLinkVariable('voucherId');

        if (is_numeric($voucherId) && $voucherId > 0) {
//update value in context variable
            Blyn::app()->getActiveOperation()->addContextVariable('voucherId', $voucherId);
        } else {
            if ($voucherId == NULL) {
                //try to find from context variable
                $voucherId = Blyn::app()->getActiveOperation()->getContextVariable('voucherId');
            }
        }

        if (is_numeric($voucherId) && $voucherId > 0) {
            $voucherTable = new BASpaceSheet('voucher');
            return $voucherTable->getListById($voucherId);
        }
        return FALSE;
    }

    public function getCurrentApplyPermit($data = NULL) {
        $applyPermitId = $this->activeLink->getLinkVariable('applyPermitId');

        if (is_numeric($applyPermitId) && $applyPermitId > 0) {
//update value in context variable
            Blyn::app()->getActiveOperation()->addContextVariable('applyPermitId', $applyPermitId);
        } else {
            if ($applyPermitId == NULL) {
                //try to find from context variable
                $applyPermitId = Blyn::app()->getActiveOperation()->getContextVariable('applyPermitId');
            }
        }

        if (is_numeric($applyPermitId) && $applyPermitId > 0) {
            $permitTable = new BASpaceSheet('permit');
            return $permitTable->getListById($applyPermitId);
        }
        return FALSE;
    }

    /*
      public function getUserVoucherList($preVoucherType = NULL, $userInfo = NULL) {

      $voucherList = array();

      if ($userInfo == NULL) {
      $userInfo = array();
      $userInfo['userId'] = Blyn::app()->getCurrentUser()->getId();
      }

      $userCooker = new BAUserCooker();
      $oUserInfo = $userCooker->getUserInfo($userInfo);

      if ($oUserInfo != NULL) {
      $itemContext = array();
      $itemContext['userInfoId'] = $oUserInfo->getId();
      if ($preVoucherType != NULL) {
      $itemContext['preVoucherType'] = $preVoucherType;
      }

      $voucherTable = new BASpaceSheet('voucher');
      $voucherList = $voucherTable->getView(array('itemData' => $itemContext));
      }
      return $voucherList;
      }
     * 
     */

    public function getUserVoucher($voucherType = NULL, $userInfo = NULL) {
        $voucherList = array();
        $voucherType = $this->getVoucherType($voucherType);

        /*
          if ($userInfo == NULL) {
          $userInfo = array();
          $userInfo['userId'] = Blyn::app()->getCurrentUser()->getId();
          }
         * 
         */

        $userCooker = new BAUserCooker();
        $oUserInfo = $userCooker->getUserInfo();

        if ($oUserInfo != NULL) {
            $itemContext = array();
            $itemContext['userInfoId'] = $oUserInfo->getId();
            if ($voucherType != NULL) {
                $itemContext['voucherTypeId'] = $voucherType->getId();
            }

            $voucherTable = new BASpaceSheet('voucher', $voucherType);
            $voucher = $voucherTable->getList(array('itemData' => $itemContext));
            return $voucher;
        }
        return FALSE;
    }

    public static function getPermitList($format = 'aliasList') {
        return array(
            self::Permit_Allow_Add => '直接添加',
            self::Permit_Allow_Approve => '需要审批',
                //self::Permit_Allow_AddVoucher_For_Birthday => '生日添加'
        );
    }

    public static function getPermitAlias($permit) {
        $permitData = self::getPermitList();

        if (isset($permitData[$permit]))
            return $permitData[$permit];
    }

    /*
      public function getUserVoucherApplyList($permit = self::Permit_Allow_AddVoucher) {

      $applyList = array();

      $permitCooker = new BAPermitCooker();

      //先获取领取代金券许可表
      $permitData = array();
      $permitData['permit'] = $permit;
      $permitData['preVoucherType'] = self::VoucherType_Voucher_Voucher;
      $permitList = $permitCooker->getUserPermitList($permitData);

      //检查每个许可是否被用户使用过，如果没使用过，就加入申请列表
      foreach ($permitList as $id => $permit) {
      $typeId = $permit->getItem('voucherTypeId')->getValue();
      $type = $this->getVoucherType($typeId);
      $voucher = $this->getUserVoucher($type, array('userId' => $user->getId(), 'permitId' => $id));
      if ($voucher == NULL) {
      $applyList[$typeId] = $type;
      }
      }

      return $applyList;
      }
     * 
     */

    public function getApplyPermitList() {

        $permitView = array();

        $voucherType = $this->getCurrentVoucherType();

        if ($voucherType != NULL) {
            $permitData = array();
            $permitData['voucherTypeId'] = $voucherType->getId();

            $permitCooker = new BAPermitCooker();
            $permitView = $permitCooker->getPermitList($permitData);
        }

        return $permitView;
    }

    public function onShowAddApplyPermit() {

        $theModel = new BDynamicFormModel();

        $permitField = 'media_permit_addVoucher_permit';
        $roleIdField = 'media_roleId_addVoucher_permit';
        $expireTimeField = 'media_expireTime_addVoucher_permit';

        $theModel->addField($permitField);
        $theModel->addField($roleIdField);
        $theModel->addField($expireTimeField);

        $this->updateControl->addRenderView('applyPermitAdd', 'voucherType_applyPermit_add', array(
            'model' => $theModel,
            'permitField' => $permitField,
            'roleIdField' => $roleIdField,
            'expireTimeField' => $expireTimeField
        ));
    }

    public function showApplyPermitList($control = NULL) {
        $renderControl = $this->updateControl;
        if ($control != NULL) {
            $renderControl = $control;
        }

        $renderControl->addRenderView('applyPermitList', 'voucherType_applyPermit_list', array(
            'permitView' => $this->getApplyPermitList(),
        ));
        $renderControl->render();
    }

    public function onAddApplyPermit() {

        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'addVoucher_permit');

        $permitData = array();
        foreach ($mediaList as $media) {
            if ($media->content != NULL)
                $permitData[$media->name] = $media->content;
        }

        $permitCooker = new BAPermitCooker();
        $permitType = $permitCooker->getCurrentPermitType();
        if ($permitType != NULL) {
            $permitData['permitTypeId'] = $permitType->getId();
        }

        $this->addVoucherTypePermit($permitData);

        /*
          $voucherType = $this->getCurrentVoucherType();
          $permitData['voucherTypeId'] = $voucherType->getId();

          $permitCooker = new BAPermitCooker();

          $permitCooker->addPermit($permitData);
         * 
         */

        $this->onShowApplyPermitList();
    }

    public function onShowApplyPermitList() {
        $permitView = $this->getApplyPermitList();
        $this->updateControl->addRenderView('permitList', 'voucherType_applyPermit_list', array(
            'permitView' => $permitView
        ));
    }

    public function addVoucherTypePermit($permitData, $voucherType = NULL) {
        if ($voucherType == NULL) {
            $voucherType = $this->getCurrentVoucherType();
        }
        if ($voucherType != NULL) {
            $preVoucherType = $this->getPreVoucherTypeFromVoucherType($voucherType);
            if (!is_array($permitData)) {
                $permitData = array();
            }
            $permitData['voucherTypeId'] = $voucherType->getId();
            if ($preVoucherType != NULL) {
                $permitData['preVoucherType'] = $preVoucherType;
            }

            $permitCooker = new BAPermitCooker();
            $permit = $permitCooker->getPermit($permitData);
            if ($permit == NULL) {
                $permit = $permitCooker->addPermit($permitData);
            }
            return $permit;
        }
        return FALSE;
    }

    public function getAllBirthPermitForVoucher() {
        $permitData = array(
            'permit' => self::Permit_Allow_Add,
            'voucherTypeId' => NULL
        );

        $permitCooker = new BAPermitCooker();

        //找出VOUCHER所有的生日许可
        //THIS IS TIME-EXPENSIVE METHOD, so use cache to save 24 hours
        $list = Blyn::app()->getActiveSpace()->getCache('allActiveBirthPermitForVoucher');
        //$list = NULL;
        if ($list == NULL || (!is_array($list))) {
            $list = $permitCooker->getAllActiveBirthPermit($permitData);
            Blyn::app()->getActiveSpace()->setCache('allActiveBirthPermitForVoucher', $list, 24 * 60 * 60);
        }
        return $list;
    }

    public function getAllLongBillIntervalPermitListForVoucher() {
        $permitData = array(
            'permit' => self::Permit_Allow_Add,
            'voucherTypeId' => NULL
        );

        $permitCooker = new BCafePermitCooker();

        //找出VOUCHER所有的生日许可
        //THIS IS TIME-EXPENSIVE METHOD, so use cache to save 24 hours,
        //每天更新一次
        $list = Blyn::app()->getActiveSpace()->getCache('allActiveLongBillIntervalPermitForVoucher');
        //$list = NULL;
        if ($list == NULL || !is_array($list)) {
            $list = $permitCooker->getAllActiveLongBillIntervalPermit($permitData);
            Blyn::app()->getActiveSpace()->setCache('allActiveLongBillIntervalPermitForVoucher', $list, 24 * 60 * 60);
        }
        return $list;
    }

    /**
     * 这个函数会找出机构所有的有效的生日代金券，如果没有发送过微信消息，就发送，如果发送过，就
     * 不再发送
     * 这个函数比较消耗时间，应该在系统不忙的时候执行
     */
    public static function sendWechatMessageForApplyBirthVoucher() {

        $voucherCooker = new BAVoucherCooker();

        $voucherBirthPermitList = $voucherCooker->getAllBirthPermitForVoucher();

        //找出用户所有的申请列表
        foreach ($voucherBirthPermitList as $birthPermit) {
            $userInfo = $birthPermit['userInfo'];
            $permit = $birthPermit['permit'];
            $voucherTypeId = $permit->getItem('voucherTypeId')->getValue();
            $voucher = $voucherCooker->getUserVoucher($voucherTypeId, $userInfo);

            $voucherType = $voucherCooker->getVoucherType($voucherTypeId);
            $typeAttributeTable = new BAAttributeSheet($voucherType);
            $typeList = $typeAttributeTable->getList(array('itemData' => array('voucherTypeId' => $voucherTypeId)));
            if ($typeList->getItem('money') != NULL) {
                $voucherMoney = $typeList->getItem('money')->getValue();
            }
            if ($typeList->getItem('alias') != NULL) {
                $voucherAlias = $typeList->getItem('alias')->getValue();
            }
            if ($voucher == NULL) {//说明代金券还没有被申请
                $wechatMessageTable = new BASheet('wechatMessage');
                $itemData = array(
                    'userInfoId' => $userInfo->getId(),
                    'permitId' => $permit->getId()
                );
                $list = $wechatMessageTable->getList(array('itemData' => $itemData));
                if ($list == NULL) {//说明还没有发送微信信息
                    //DO SENDING MESSAGE TO WECHAT here
                    $openid = '';
                    if ($userInfo->getItem('openid')) {
                        $openid = $userInfo->getItem('openid')->getValue();
                    }
                    $options = array(
                        'appid' => 'wxdfdd543f3624de1a',
                        'appsecret' => '0d263ad0ccbd55da5f61b105ffd90ef8'
                    );
                    $weObj = new BAWechatCooker($options);
                    //点击微信消息，跳转到“我的代金券”
                    $sendTemplateMessageControl2 = new BUIControl('sendTemplateMessage2');
                    $myUrl = $sendTemplateMessageControl2->getAjaxLinkUrl('showCardUserBillListInMobile', NULL, array(
                        'cooker' => 'BAVoucher@showUserVoucherListInMobile',
                    ));
                    $data = array(
                        'touser' => $openid, //$wxOpenid
                        'template_id' => 'gBMt2LTe8nbNRRTfoZFwtKw1EiucgpGBuXgIkMBzkDg', //kUcnkiodpWpNQcT6tRKbcuFCNyZSIeg-xBpJkDFCQ1g//0sEg7RAxt2Z0q4Y5Qv8WZIMrhYa-mycc8glbtWaGXVQ
                        'url' => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdfdd543f3624de1a&redirect_uri=http://hamshun.sinaapp.com/maozhua/2.php&response_type=code&scope=snsapi_base&state=1#wechat_redirect',
                        'topcolor' => '#FF0000',
                        'data' => array(
                            'first' => array(
                                'value' => '亲, 猫抓送您一张' . $voucherAlias . '，一般人我不送的哦。',
                                'color' => '#000000'
                            ),
                            'keyword1' => array(
                                'value' => '代金券', //礼券
                                'color' => '#000000'
                            ),
                            'keyword2' => array(
                                'value' => $voucherMoney . '元', //金额
                                'color' => '#000000'
                            ),
                            'keyword3' => array(
                                'value' => '自领取之日即可使用', //生效日期
                                'color' => '#000000'
                            ),
                            'remark' => array(
                                'value' => '请到会员中心领取代金券，如有疑问请咨询023-86577788',
                                'color' => '#000000'
                            ),
                        )
                    );
                    $res = $weObj->sendTemplateMessage($data);
                    if ($res["errcode"] == 0) {
                        //发送消息成功
                        $itemData['sendTime'] = time();

                        $wechatMessageTable->addList($itemData);
                    }
                }
            }
        }
    }

    /**
     * 这个函数会找出来长时间没有回访的客户，然后发送微信信息
     */
    public static function sendWechatMessageForLongBillIntervalVoucher() {
        $voucherCooker = new BAVoucherCooker();

        $voucherPermitList = $voucherCooker->getAllLongBillIntervalPermitListForVoucher();

        //找出用户所有的申请列表
        foreach ($voucherPermitList as $permitData) {
            $userInfo = $permitData['userInfo'];
            $permit = $permitData['permit'];
            $voucherTypeId = $permit->getItem('voucherTypeId')->getValue();
            $voucher = $voucherCooker->getUserVoucher($voucherTypeId, $userInfo);

            $voucherType = $voucherCooker->getVoucherType($voucherTypeId);
            $typeAttributeTable = new BAAttributeSheet($voucherType);
            $typeList = $typeAttributeTable->getList(array('itemData' => array('voucherTypeId' => $voucherTypeId)));
            if ($typeList->getItem('money') != NULL) {
                $voucherMoney = $typeList->getItem('money')->getValue();
            }
            if ($typeList->getItem('alias') != NULL) {
                $voucherAlias = $typeList->getItem('alias')->getValue();
            }
            if ($voucher == NULL) {//说明代金券还没有被申请
                $wechatMessageTable = new BASheet('wechatMessage');
                $itemData = array(
                    'userInfoId' => $userInfo->getId(),
                    'permitId' => $permit->getId()
                );
                $list = $wechatMessageTable->getList(array('itemData' => $itemData));
                if ($list == NULL) {//说明还没有发送微信信息
                    //DO SENDING MESSAGE TO WECHAT here
                    $openid = '';
                    if ($userInfo->getItem('openid')) {
                        $openid = $userInfo->getItem('openid')->getValue();
                    }
                    $options = array(
                        'appid' => 'wxdfdd543f3624de1a',
                        'appsecret' => '0d263ad0ccbd55da5f61b105ffd90ef8'
                    );
                    $weObj = new BAWechatCooker($options);
                    //点击微信消息，跳转到“我的代金券”
                    $sendTemplateMessageControl3 = new BUIControl('sendTemplateMessage3');
                    $myUrl = $sendTemplateMessageControl3->getAjaxLinkUrl('showCardUserBillListInMobile', NULL, array(
                        'cooker' => 'BAVoucher@showUserVoucherListInMobile',
                    ));
                    $data = array(
                        'touser' => $openid, //$wxOpenid
                        'template_id' => 'gBMt2LTe8nbNRRTfoZFwtKw1EiucgpGBuXgIkMBzkDg', //kUcnkiodpWpNQcT6tRKbcuFCNyZSIeg-xBpJkDFCQ1g//0sEg7RAxt2Z0q4Y5Qv8WZIMrhYa-mycc8glbtWaGXVQ
                        'url' => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdfdd543f3624de1a&redirect_uri=http://hamshun.sinaapp.com/maozhua/2.php&response_type=code&scope=snsapi_base&state=1#wechat_redirect',
                        'topcolor' => '#FF0000',
                        'data' => array(
                            'first' => array(
                                'value' => '亲, 猫抓送您一张' . $voucherAlias . '，一般人我不送的哦。',
                                'color' => '#000000'
                            ),
                            'keyword1' => array(
                                'value' => '代金券', //礼券
                                'color' => '#000000'
                            ),
                            'keyword2' => array(
                                'value' => $voucherMoney . '元', //金额
                                'color' => '#000000'
                            ),
                            'keyword3' => array(
                                'value' => '自领取之日即可使用', //生效日期
                                'color' => '#000000'
                            ),
                            'remark' => array(
                                'value' => '请到会员中心领取代金券，如有疑问请咨询023-86577788',
                                'color' => '#000000'
                            ),
                        )
                    );
                    $res = $weObj->sendTemplateMessage($data);
                    if ($res["errcode"] == 0) {
                        //发送消息成功
                        $itemData['sendTime'] = time();

                        $wechatMessageTable->addList($itemData);
                    }
                }
            }
        }
    }

}
